<!DOCTYPE HTML>
<html>

<head>
    <meta charset="utf-8">
    <title>菜鸟教程(runoob.com)</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font: 13px Helvetica, Arial;
        }
        
        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }
        
        form input {
            border: 0;
            padding: 10px;
            width: 90%;
            margin-right: .5%;
        }
        
        form button {
            width: 9%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }
        
        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }
        
        #messages li {
            padding: 5px 10px;
        }
        
        #messages li:nth-child(odd) {
            background: #eee;
        }
    </style>
    <script src="socket.io.js"></script>
    <script type="text/javascript">
        'use strict'
        /**
            Connection 必须设置 Upgrade，表示客户端希望连接升级。
            Upgrade 字段必须设置 Websocket，表示希望升级到 Websocket 协议。

            Sec-WebSocket-Key 是随机的字符串，服务器端会用这些数据来构造出一个 SHA-1 的信息摘要。

            把 “Sec-WebSocket-Key” 加上一个特殊字符串 “258EAFA5-E914-47DA-95CA-C5AB0DC85B11”，
            然后计算 SHA-1 摘要，之后进行 BASE-64 编码，将结果做为 “Sec-WebSocket-Accept” 头的值，返回给客户端。

            如此操作，可以尽量避免普通 HTTP 请求被误认为 Websocket 协议。
            Sec-WebSocket-Version 表示支持的 Websocket 版本。RFC6455 要求使用的版本是 13，之前草案的版本均应当弃用。
            
            Origin 字段是可选的，通常用来表示在浏览器中发起此 Websocket 连接所在的页面，类似于 Referer。
            但是，与 Referer 不同的是，Origin 只包含了协议和主机名称。
            其他一些定义在 HTTP 协议中的字段，如 Cookie 等，也可以在 Websocket 中使用。
        */
        //需要在服务声明websocket 服务，才能使用
        function WebSocketTest() {
            if ("WebSocket" in window) {
                // 打开一个 web socket
                var ws = new WebSocket("ws://localhost:8181/");

                ws.onopen = function() {
                    // Web Socket 已连接上，使用 send() 方法发送数据
                    ws.send("发送数据");
                    alert("数据发送中...");
                };

                ws.onmessage = function(evt) {
                    var received_msg = evt.data;
                    alert("数据已接收：" + received_msg);
                    let time = setTimeout(function() {
                        //关闭连接
                        ws.close();
                        clearTimeout(time)
                    }, 1000)
                };

                ws.onclose = function() {
                    // 关闭 websocket 事件监听
                    alert("连接已关闭...");
                };

            } else {
                // 浏览器不支持 WebSocket
                alert("您的浏览器不支持 WebSocket!");
            }
        }
        /*
	        websocket 和 socket 的区别。

			软件通信有七层结构，
				下三层结构偏向与数据通信，上三层更偏向于数据处理，
				中间的传输层则是连接上三层与下三层之间的桥梁，
				每一层都做不同的工作，上层协议依赖与下层协议。基于这个通信结构的概念。

			Socket 其实并不是一个协议，是应用层与 TCP/IP 协议族通信的中间软件抽象层，它是一组接口。
			当两台主机通信时，让 Socket 去组织数据，
			以符合指定的协议。TCP 连接则更依靠于底层的 IP 协议，IP 协议的连接则依赖于链路层等更低层次。

			WebSocket 则是一个典型的应用层协议。

			总的来说：Socket 是传输控制层协议，WebSocket 是应用层协议。
         */
    </script>

</head>

<body>

    <div id="sse">
        <a href="javascript:WebSocketTest()">运行 WebSocket</a>
    </div>

</body>

</html>